#include "comm/my_thread_base.h"
#include "comm/my_mem.h"
#include "comm/my_log.h"

void my_test(my_thread_base_t *thread_base)
{
    (void)thread_base;

    void *ptr1 = my_thread_malloc(100);
    void *ptr2 = my_thread_malloc(100);
    void *ptr3 = my_thread_malloc(100);
    my_thread_free(ptr1);
    my_thread_free(ptr2);
    my_thread_free(ptr3);
    ptr1 = my_thread_malloc(100);
    ptr2 = my_thread_malloc(100);
    ptr3 = my_thread_malloc(100);
    my_thread_free(ptr1);
    my_thread_free(ptr2);
    my_thread_free(ptr3);
}

static const char *test_a = "test_a";
static const char *test_b = "test_b";
static const char *test_c = "test_c";

void my_test_thread_store(my_thread_base_t *thread_base)
{
    (void)thread_base;

    void *ptr;
    my_thread_store_safe_put(test_a, "aaa");
    ptr = my_thread_store_get(test_a);
    if (ptr != (void *)"aaa") {
        MY_LOG_FATAL("except %p, but got other", "aaa");
    }
    my_thread_store_del(test_a);
    ptr = my_thread_store_get("test_a");
    if (ptr != NULL) {
        MY_LOG_FATAL("except NULL, but got other");
    }

    my_thread_store_safe_put(test_b, "bbb");
    my_thread_store_safe_put(test_c, "ccc");

    ptr = my_thread_store_get(test_b);
    if (ptr != (void *)"bbb") {
        MY_LOG_FATAL("except %p, but got other", "bbb");
    }

    ptr = my_thread_store_get(test_c);
    if (ptr != (void *)"ccc") {
        MY_LOG_FATAL("except %p, but got other", "ccc");
    }
}

int main()
{
    my_test(NULL);

    my_thread_base_t thread_base;
    bzero(&thread_base, sizeof(my_thread_base_t));

    my_thread_base_start(&thread_base, my_test, NULL, 1, 1);
    my_thread_base_join(&thread_base, NULL);

    my_test(NULL);

    bzero(&thread_base, sizeof(my_thread_base_t));
    my_thread_base_start(&thread_base, my_test, NULL, 0, 0);
    my_thread_base_join(&thread_base, NULL);

    my_test(NULL);

    my_mem_pool_init(&g_mem_pool, 1, my_mem_alloc, my_mem_free);
    my_4kaligned_mem_pool_init(&g_4kaligned_mem_pool, 1,
        my_aligned_malloc,
        my_aligned_free);

    my_test(NULL);

    bzero(&thread_base, sizeof(my_thread_base_t));
    my_thread_base_start(&thread_base, my_test, NULL, 1, 1);
    my_thread_base_join(&thread_base, NULL);

    my_test(NULL);

    bzero(&thread_base, sizeof(my_thread_base_t));
    my_thread_base_start(&thread_base, my_test, NULL, 0, 0);
    my_thread_base_join(&thread_base, NULL);

    my_test(NULL);

    bzero(&thread_base, sizeof(my_thread_base_t));
    my_thread_base_start(&thread_base, my_test_thread_store, NULL, 0, 0);
    my_thread_base_join(&thread_base, NULL);

    my_mem_pool_clean(&g_mem_pool);
    my_4kaligned_mem_pool_clean(&g_4kaligned_mem_pool);

    my_mem_assert_leak();

    MY_LOG_DEBUG("test pass");
    return 0;
}